package com.christina.engine.processing;

import com.christina.engine.processing.model.ProcessingContext;
import com.christina.engine.processing.model.ProcessingEvent;
import com.christina.engine.processing.model.ProcessingEventType;
import com.christina.engine.processing.model.ProcessingResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 请求处理器责任链管理器
 * 负责管理处理器的注册、排序和执行
 */
@Component
public class RequestProcessorChain {
    
    private static final Logger logger = LoggerFactory.getLogger(RequestProcessorChain.class);
    
    private final Map<String, RequestProcessor> processors = new ConcurrentHashMap<>();
    private volatile RequestProcessor chainHead;
    private volatile boolean chainBuilt = false;
    
    /**
     * 注册处理器到责任链
     * 
     * @param processor 要注册的处理器
     */
    public void registerProcessor(RequestProcessor processor) {
        if (processor == null) {
            throw new IllegalArgumentException("Processor cannot be null");
        }
        
        String name = processor.getName();
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("Processor name cannot be null or empty");
        }
        
        logger.info("Registering processor: {} with order: {}", name, processor.getOrder());
        processors.put(name, processor);
        chainBuilt = false; // 标记需要重新构建链
    }
    
    /**
     * 注销处理器
     * 
     * @param processorName 处理器名称
     * @return 如果成功注销返回true，否则返回false
     */
    public boolean unregisterProcessor(String processorName) {
        if (processorName == null || processorName.trim().isEmpty()) {
            return false;
        }
        
        RequestProcessor removed = processors.remove(processorName);
        if (removed != null) {
            logger.info("Unregistered processor: {}", processorName);
            chainBuilt = false; // 标记需要重新构建链
            return true;
        }
        
        return false;
    }
    
    /**
     * 获取已注册的处理器
     * 
     * @param processorName 处理器名称
     * @return 处理器实例，如果不存在返回null
     */
    public RequestProcessor getProcessor(String processorName) {
        return processors.get(processorName);
    }
    
    /**
     * 获取所有已注册的处理器名称
     * 
     * @return 处理器名称列表
     */
    public List<String> getProcessorNames() {
        return new ArrayList<>(processors.keySet());
    }
    
    /**
     * 获取已注册的处理器数量
     * 
     * @return 处理器数量
     */
    public int getProcessorCount() {
        return processors.size();
    }
    
    /**
     * 检查责任链是否启用
     * 
     * @return 如果有启用的处理器返回true，否则返回false
     */
    public boolean isEnabled() {
        return getEnabledProcessorCount() > 0;
    }
    
    /**
     * 检查处理器是否已注册
     * 
     * @param processorName 处理器名称
     * @return 如果已注册返回true，否则返回false
     */
    public boolean isProcessorRegistered(String processorName) {
        return processors.containsKey(processorName);
    }
    
    /**
     * 构建责任链
     * 根据处理器的order属性进行排序，并建立链式关系
     */
    private void buildChain() {
        if (chainBuilt && chainHead != null) {
            return;
        }
        
        synchronized (this) {
            if (chainBuilt && chainHead != null) {
                return;
            }
            
            logger.info("Building processor chain with {} processors", processors.size());
            
            if (processors.isEmpty()) {
                chainHead = null;
                chainBuilt = true;
                return;
            }
            
            // 按order排序处理器
            List<RequestProcessor> sortedProcessors = processors.values().stream()
                    .filter(RequestProcessor::isEnabled)
                    .sorted(Comparator.comparingInt(RequestProcessor::getOrder))
                    .collect(Collectors.toList());
            
            if (sortedProcessors.isEmpty()) {
                logger.warn("No enabled processors found");
                chainHead = null;
                chainBuilt = true;
                return;
            }
            
            // 建立链式关系
            for (int i = 0; i < sortedProcessors.size() - 1; i++) {
                sortedProcessors.get(i).setNext(sortedProcessors.get(i + 1));
            }
            
            // 最后一个处理器的next设为null
            sortedProcessors.get(sortedProcessors.size() - 1).setNext(null);
            
            chainHead = sortedProcessors.get(0);
            chainBuilt = true;
            
            logger.info("Processor chain built successfully. Chain order: {}", 
                    sortedProcessors.stream()
                            .map(RequestProcessor::getName)
                            .collect(Collectors.joining(" -> ")));
        }
    }
    
    /**
     * 执行责任链处理
     * 
     * @param context 处理上下文
     * @return 处理结果
     */
    public ProcessingResult process(ProcessingContext context) {
        if (context == null) {
            throw new IllegalArgumentException("Processing context cannot be null");
        }
        
        // 确保链已构建
        buildChain();
        
        if (chainHead == null) {
            logger.warn("No processors available in chain");
            return ProcessingResult.failure("No processors available in chain");
        }
        
        logger.debug("Starting chain processing for request: {}", context.getRequestId());
        
        // 添加链处理开始事件
        context.addEvent(ProcessingEvent.builder()
                .type(ProcessingEventType.REQUEST_RECEIVED)
                .message("Chain processing started")
                .source(this)
                .eventData("processorCount", getEnabledProcessorCount())
                .build());
        
        long chainStartTime = System.currentTimeMillis();
        
        try {
            // 执行责任链
            ProcessingResult result = executeChain(context);
            
            long chainExecutionTime = System.currentTimeMillis() - chainStartTime;
            
            // 添加链处理完成事件
            context.addEvent(ProcessingEvent.builder()
                    .type(result.isSuccess() ? ProcessingEventType.SERVICE_EXECUTED : ProcessingEventType.ERROR_OCCURRED)
                    .message("Chain processing " + (result.isSuccess() ? "completed" : "failed"))
                    .source(this)
                    .eventData("chainExecutionTimeMs", chainExecutionTime)
                    .eventData("success", result.isSuccess())
                    .build());
            
            logger.debug("Chain processing completed for request: {} in {}ms, success: {}", 
                    context.getRequestId(), chainExecutionTime, result.isSuccess());
            
            return result;
            
        } catch (Exception e) {
            long chainExecutionTime = System.currentTimeMillis() - chainStartTime;
            logger.error("Error during chain processing for request: {}", context.getRequestId(), e);
            
            // 添加链处理错误事件
            context.addEvent(ProcessingEvent.errorOccurred(
                    "Chain processing error: " + e.getMessage(), e));
            
            return ProcessingResult.failure(
                    "Chain processing error: " + e.getMessage(),
                    e,
                    "RequestProcessorChain"
            );
        }
    }
    
    /**
     * 获取启用的处理器数量
     * 
     * @return 启用的处理器数量
     */
    private int getEnabledProcessorCount() {
        return (int) processors.values().stream()
                .filter(RequestProcessor::isEnabled)
                .count();
    }
    
    /**
     * 执行责任链
     * 
     * @param context 处理上下文
     * @return 处理结果
     */
    private ProcessingResult executeChain(ProcessingContext context) {
        RequestProcessor current = chainHead;
        ProcessingResult lastResult = ProcessingResult.success("ChainStart");
        
        while (current != null) {
            ProcessingResult result = current.process(context);
            
            // 如果处理失败或者不应该继续，停止链执行
            if (!result.isSuccess() || !result.isShouldContinue()) {
                return result;
            }
            
            lastResult = result;
            current = current.getNext();
        }
        
        return lastResult;
    }
    
    /**
     * 重新构建责任链
     * 强制重新构建处理器链，通常在处理器配置发生变化时调用
     */
    public void rebuildChain() {
        synchronized (this) {
            chainBuilt = false;
            chainHead = null;
            logger.info("Chain rebuild requested");
        }
        buildChain();
    }
    
    /**
     * 清空所有处理器
     */
    public void clear() {
        synchronized (this) {
            processors.clear();
            chainHead = null;
            chainBuilt = false;
            logger.info("All processors cleared");
        }
    }
    
    /**
     * 获取责任链的详细信息
     * 
     * @return 链信息
     */
    public ChainInfo getChainInfo() {
        buildChain(); // 确保链已构建
        
        List<ProcessorInfo> processorInfos = processors.values().stream()
                .map(processor -> new ProcessorInfo(
                        processor.getName(),
                        processor.getOrder(),
                        processor.isEnabled(),
                        processor.getClass().getSimpleName()
                ))
                .sorted(Comparator.comparingInt(ProcessorInfo::getOrder))
                .collect(Collectors.toList());
        
        return new ChainInfo(
                processors.size(),
                getEnabledProcessorCount(),
                chainBuilt,
                processorInfos
        );
    }
    
    /**
     * 处理器信息
     */
    public static class ProcessorInfo {
        private final String name;
        private final int order;
        private final boolean enabled;
        private final String className;
        
        public ProcessorInfo(String name, int order, boolean enabled, String className) {
            this.name = name;
            this.order = order;
            this.enabled = enabled;
            this.className = className;
        }
        
        public String getName() { return name; }
        public int getOrder() { return order; }
        public boolean isEnabled() { return enabled; }
        public String getClassName() { return className; }
        
        @Override
        public String toString() {
            return String.format("%s(order=%d, enabled=%s, class=%s)", 
                    name, order, enabled, className);
        }
    }
    
    /**
     * 责任链信息
     */
    public static class ChainInfo {
        private final int totalProcessors;
        private final int enabledProcessors;
        private final boolean chainBuilt;
        private final List<ProcessorInfo> processors;
        
        public ChainInfo(int totalProcessors, int enabledProcessors, 
                        boolean chainBuilt, List<ProcessorInfo> processors) {
            this.totalProcessors = totalProcessors;
            this.enabledProcessors = enabledProcessors;
            this.chainBuilt = chainBuilt;
            this.processors = new ArrayList<>(processors);
        }
        
        public int getTotalProcessors() { return totalProcessors; }
        public int getEnabledProcessors() { return enabledProcessors; }
        public boolean isChainBuilt() { return chainBuilt; }
        public List<ProcessorInfo> getProcessors() { return new ArrayList<>(processors); }
        
        @Override
        public String toString() {
            return String.format("ChainInfo{total=%d, enabled=%d, built=%s, processors=%s}", 
                    totalProcessors, enabledProcessors, chainBuilt, processors);
        }
    }
}